<?php
declare (strict_types=1);

namespace app\admin\controller\system;

use think\Response;
use app\common\enum\SystemEnum;
use hg\apidoc\annotation as Apidoc;
use think\db\exception\DbException;
use app\common\model\system\MenuModel;
use app\common\cache\system\MenuCache;
use app\common\controller\AdminController;
use app\common\validate\system\MenuValidate;

/**
 * @Apidoc\Title("菜单管理")
 * @Apidoc\Group("adminSystem")
 * @Apidoc\Sort("300")
 */
class Menu extends AdminController
{
    /**
     * 初始化方法
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();
        $this->model = new MenuModel();
    }

    /**
     * @Apidoc\Title("列表")
     * @Apidoc\Param("type",type="string",desc="菜单返回类型[list,tree],默认为树形")
     * @Apidoc\Returned(ref="app\common\model\system\MenuModel")
     * @return Response
     * @throws DbException
     */
    public function index(): Response
    {
        $user_info = $this->cache_user_info;          //登录后的用户缓存信息
        $data      = MenuCache::get($user_info['id']);//获取菜单缓存
        if (empty($data)) {
            $where = [];
            //如果用户是普通管理员-获取用户角色对应的菜单
            if ($user_info['is_super'] === 0) {
                $menu_ids = get_menu_id($user_info['role_ids']);
                $where[]  = ['id', 'in', $menu_ids];//根据角色的包含的菜单ID查询
                $where[]  = ['is_disable', '=', 0]; //菜单未禁用
            }

            $order = ['sort' => 'desc', 'id' => 'asc'];
            $data  = $this->model->where($where)->order($order)->select();
            if ($data->isEmpty()) {
                return $this->error(SystemEnum::DATA_NOT_EXIST);
            }
            $data = $data->toArray();
            MenuCache::set($user_info['id'], $data);
        }

        if (empty($this->param['type']) || $this->param['type'] == 'tree') {
            return $this->result(list_to_tree($data));
        } else {
            return $this->result($data);
        }
    }

    /**
     * @Apidoc\Title("添加")
     * @Apidoc\Method("POST")
     * @Apidoc\Param(ref="app\common\model\system\MenuModel",withoutField="id,create_time,update_time,delete_time")
     * @Apidoc\Returned(ref="app\common\model\system\MenuModel")
     */
    public function add(): Response
    {
        $this->validate($this->param, MenuValidate::class, 'add');
        $data = $this->model;
        $data->save($this->param);
        return $this->result($data->toArray());
    }

    /**
     * @Apidoc\Title("详情")
     * @Apidoc\Param(ref="app\common\model\system\MenuModel",field="id")
     * @Apidoc\Returned(ref="app\common\model\system\MenuModel")
     */
    public function read(): Response
    {
        $this->validate($this->param, MenuValidate::class, 'read');
        $data = MenuCache::get($this->param['id']);
        if (empty($data)) {
            $data = $this->model->findOrEmpty($this->param['id']);
            if ($data->isEmpty()) {
                return $this->error(SystemEnum::DATA_NOT_EXIST);
            }
            $data = $data->toArray();
            MenuCache::set($this->param['id'], $data);
        }
        return $this->result($data);
    }

    /**
     * @Apidoc\Title("修改")
     * @Apidoc\Method("POST")
     * @Apidoc\Param(ref="app\common\model\system\MenuModel",withoutField="create_time,update_time,delete_time")
     * @Apidoc\Returned(ref="app\common\model\system\MenuModel")
     * @return Response
     */
    public function edit(): Response
    {
        $this->validate($this->param, MenuValidate::class, 'edit');
        $data = $this->model->findOrEmpty($this->param['id']);
        if ($data->isEmpty()) {
            return $this->error(SystemEnum::EDIT_DATA_ERROR);
        } else {
            $data->save($this->param);
        }
        return $this->result($data->toArray());
    }

    /**
     * @Apidoc\Title("删除")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("id",type="array|int",desc="主键ID")
     * @return Response
     */
    public function del(): Response
    {
        $this->validate($this->param, MenuValidate::class, 'del');
        $data = $this->model->destroy($this->param['id']);
        if ($data) {
            return $this->result([]);
        }
        return $this->error(SystemEnum::DELETE_DATA_ERROR);
    }
}
